﻿// InjectDll.cpp : 定义 DLL 应用程序的导出函数。
//

#include "Precompiled.hpp"
#define INJECTLIBAPI extern "C" __declspec(dllexport)
#include "WalleLib.hpp"
#include "resource.h"
#include <stdio.h>
#include "logger.hpp"
#include "read_data.hpp"

#if defined(_DEBUG)
// This function forces the debugger to be invoked
void ForceDebugBreak() {
    __try { DebugBreak(); }
    __except(UnhandledExceptionFilter(GetExceptionInformation())) { }
}
#else
#define ForceDebugBreak()
#endif



// Instruct the compiler to put the g_hhook data variable in 
// its own data section called Shared. We then instruct the 
// linker that we want to share the data in this section 
// with all instances of this application.
#pragma data_seg("Shared")
HHOOK g_hhook = NULL;
DWORD g_dwThreadIdDIPS = 0;
#pragma data_seg()

// Instruct the linker to make the Shared section
// readable, writable, and shared.
#pragma comment(linker, "/section:Shared,rws")

// Nonshared variables
HINSTANCE g_hinstDll = NULL;

// Forward references
LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);
INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);


INJECTLIBAPI BOOL WINAPI SetMessageHook(DWORD dwThreadId)
{
    BOOL fOk = FALSE;
    if (dwThreadId != 0) {
        // Make sure that the hook is not already installed.
        assert(g_hhook == NULL);

        // Save our thread ID in a shared variable so that our GetMsgProc 
        // function can post a message back to the thread when the server 
        // window has been created.
        g_dwThreadIdDIPS = GetCurrentThreadId();
        // Install the hook on the specified thread
        g_hhook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hinstDll, 
                                   dwThreadId);

        fOk = (g_hhook != NULL);
        if (fOk) {
            // The hook was installed successfully; force a benign message to 
            // the thread's queue so that the hook function gets called.
            fOk = PostThreadMessage(dwThreadId, WM_NULL, 0, 0);
            LOG() << "After post thread message to active the hook";
        }
    } else {

        // Make sure that a hook has been installed.
        assert(g_hhook != NULL);
        fOk = UnhookWindowsHookEx(g_hhook);
        g_hhook = NULL;
    }

    return(fOk);
}

LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) {

    static BOOL fFirstTime = TRUE;

    if (fFirstTime) {
        // The DLL just got injected.
        fFirstTime = FALSE;

        // Uncomment the line below to invoke the debugger 
        // on the process that just got the injected DLL.
        //ForceDebugBreak();

        // Create the DTIS Server window to handle the client request.
        HWND dlg = CreateDialog(g_hinstDll, MAKEINTRESOURCE(IDD_INJECTLIB), NULL, Dlg_Proc);
        assert(dlg != NULL);
        LOG() << "The first message is received by our message HOOK" << END;
        ShowWindow(dlg, SW_SHOW);		
    }

    return(CallNextHookEx(g_hhook, nCode, wParam, lParam));
}
#define IDT_TIMER 102

INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    static char buffer[512];
    
    switch (uMsg)
    {
    case WM_INITDIALOG:
        SetTimer(hwnd, IDT_TIMER, 100, NULL);
        return TRUE;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case ID_REFRESH:
            dumpMonsterList();
            //callDazuo();
            break;
        case ID_CANCEL:
            PostThreadMessage(g_dwThreadIdDIPS, WM_NULL, 0, 0);
            DestroyWindow(hwnd);
            return TRUE;
        }
	case WM_TIMER:
            sprintf(buffer, "血 = %d/%d",getRoleHp(), getRoleHpMax());
            SetDlgItemTextA(hwnd, IDC_HP, buffer);
            sprintf(buffer, "蓝 = %d/%d", getRoleMp(), getRoleMpMax());
            SetDlgItemTextA(hwnd, IDC_MP, buffer);
            sprintf(buffer, "等级   = %d", getRoleLevel());
            SetDlgItemTextA(hwnd, IDC_LEVEL, buffer);
            sprintf(buffer, "怪物 ID = 0x%x", getMonsterId());
            SetDlgItemTextA(hwnd, IDC_MONSTER_ID, buffer);
            return TRUE;
            break;
        
    default:
        return(FALSE);
    }
}


